package com.blueocean_health.care.management.interceptor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.blueocean_health.care.management.common.LocalManager;
import com.blueocean_health.care.management.common.base.string.StringUtils;
import com.blueocean_health.care.management.domain.base.Power;
import com.blueocean_health.care.management.domain.base.SysResult;
import com.blueocean_health.care.management.domain.base.Team;
import com.blueocean_health.care.management.domain.base.UserAccount;
import com.blueocean_health.care.management.domain.dto.RoleDto;
import com.blueocean_health.care.management.domain.vo.LoginDataVo;
import com.blueocean_health.care.management.domain.vo.TeamVo;
import com.blueocean_health.care.management.domain.vo.UserVo;
import com.blueocean_health.care.management.em.LocalManagerType;
import com.blueocean_health.care.management.mapper.PowerMapper;
import com.blueocean_health.care.management.mapper.RoleMapper;
import com.blueocean_health.care.management.mapper.TeamMapper;
import com.blueocean_health.care.management.mapper.UserAccountMapper;
import com.blueocean_health.care.management.service.LoginService;
import com.blueocean_health.care.management.service.PowerService;

/**
 * 泰心端用户校验拦截器
 * 
 * @author huyanqiu
 * @date 2018年5月22日上午11:14:31
 * @version 版本号：1.0
 */
@Component
public class AdminValidateInterceptor implements HandlerInterceptor {

	@Autowired
	private LoginService loginService;
	@Autowired
	private TeamMapper teamMapper;
	@Autowired
	private UserAccountMapper userAccountMapper;
	@Autowired
	private RoleMapper roleMapper;
	@Autowired
	private PowerMapper powerMapper;
	@Autowired
	private PowerService powerService;

	@Value("${server.context-path}")
	private String serverContextPath;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String requestURI = "/user/login/select-identity";
		String token = request.getHeader("token");
		String parameter = request.getParameter("token");
		if (!StringUtils.isEmpty(parameter)) {
			token = parameter;
		}
		LoginDataVo loginDataVo = new LoginDataVo();

		UserVo userVo = null;
		try {
			userVo = loginService.getUserInfoByToken(token);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (userVo == null) {
			return errorResult("用户验证失败", response);
		}
		loginDataVo.setUser(userVo);

		// 判断当前登录人是否被禁用/删除
		UserAccount useraccount = userAccountMapper.selectByPrimaryKey(userVo.getUserId());
		if (useraccount.getEnableStatus() == 2) {
			return errorResult("用户被禁用", response);
		} else if (useraccount.getIsActive() == 0) {
			return errorResult("用户被删除", response);
		}
		// 判断当前登录人所在组织是否被禁用/删除(过滤登录后选择身份接口)
		if (!request.getRequestURI().contains(requestURI)) {
			if (userVo.getTeamId().isEmpty()) {
				return errorResult("登录用户未选择身份", response);
			}
			Team team = teamMapper.selectByPrimaryKey(Integer.parseInt(userVo.getTeamId()));
			if (team.getIsActive() == 2) {
				return errorResult("用户所在组织已被禁用", response);
			} else if (team.getIsActive() == 3) {
				return errorResult("用户所在组织已被删除", response);
			}

			// 保存当前组织/项目信息
			loginDataVo.setCurrentTeam(team);
			TeamVo tv = new TeamVo();
			tv.setId(team.getTeamId());
			tv.setName(team.getTeamName());
			tv.setParentId(StringUtils.isEmpty(team.getParentTeamId()) ? 0 : team.getParentTeamId());
			loginDataVo.setCurrentOrg(tv);
			loginDataVo.getUser().setFirstOrg(Integer.parseInt(team.getFirstOrg()));

			// 当前用户，组织/项目下的所有角色
			List<RoleDto> currentRoles = roleMapper.findAllRoleByUserIdAndOrgId(loginDataVo.getUser().getUserId(),
					loginDataVo.getCurrentTeam().getTeamId());
			loginDataVo.setRoles(currentRoles);

			// 当前用户的所有权限
			if (!StringUtils.isEmpty(currentRoles) && currentRoles.size() > 0) {
				List<Power> allPower = powerMapper.selectAllByType(team.getType());
				loginDataVo.setAllPower(allPower);
				// 判断当前url是否需要权限访问
				boolean isAuth = false;
				for (Power p : allPower) {
					if (p.getType() == team.getType()) {
						if (request.getRequestURI().toLowerCase().contains(p.getUrl().toLowerCase())) {
							isAuth = true;
							break;
						}
					}
				}
				// 权限验证代码
				if (isAuth) {
					// 1.获取所有角色权限并集
					List<Integer> roleIds = new ArrayList<>();
					currentRoles.stream().forEach(dto -> {
						roleIds.add(dto.getId());
					});
					List<Power> powers = roleMapper.findAllPowerByRoleIds(roleIds);
					// 2.获取当前组织，当前用户所拥有的权限
					List<String> permissions = powerService.getPermissionsNew(userVo.getUserId().toString(),
							team.getTeamId().toString());
					// 3. 第一步与第二步取交集
					List<Power> truePowers = new ArrayList<>();
					if (StringUtils.isEmpty(permissions) || permissions.size() <= 0) {
						truePowers = powers;
					} else {
						for (String code : permissions) {
							for (Power p : powers) {
								if (code.equals(p.getPowerCode())) {
									truePowers.add(p);
								}
							}
						}
					}
					loginDataVo.setPowers(truePowers);

					// 4.判断是否通过验证
					boolean isPass = false;
					for (Power p : truePowers) {
						if (!StringUtils.isEmpty(p)) {
							if (request.getRequestURI().toLowerCase().contains(p.getUrl().toLowerCase())) {
								isPass = true;
								break;
							}
						}
					}
					if (!isPass) {
						return errorResult("用户无权限访问当前接口", response);
					}
				}
			} else {
				return errorResult("用户无权限访问当前接口", response);
			}
		}
		request.setAttribute("user", userVo);
		LocalManager.setVal(LocalManagerType.LOGIN_DATA, loginDataVo);
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
	}

	/**
	 * 校验失败返回数据，使用方法。
	 * 
	 * @param resultMsg
	 * @param response
	 * @return
	 * @throws IOException
	 */
	private boolean errorResult(String resultMsg, HttpServletResponse response) throws IOException {
		SysResult result = SysResult.error(SysResult.validateError, resultMsg);
		String json = JSONObject.toJSONString(result);
		response.setContentType("application/json;charset=UTF-8");
//		response.setCharacterEncoding("UTF-8");
		response.getWriter().print(json);
		return false;
	}

}
